
/*
 * Copyright (C) 2008-2009 Archie L. Cobbs. All rights reserved.
 *
 * $Id: CollectionReader.java 218 2009-11-19 18:01:57Z archie.cobbs $
 */

package org.dellroad.sidekar.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;

import org.dellroad.sidekar.schema.model.CollectionFieldModel;
import org.dellroad.sidekar.schema.model.SimpleFieldModel;

/**
 * Introspects Sidekar collection field annotations.
 */
abstract class CollectionReader extends AbstractReader {

    /**
     * Process an access method annotation.
     */
    protected void processAccessAnnotation(Annotation a, Method method, String name,
      CollectionFieldModel fieldModel, @SuppressWarnings("rawtypes") Class<? extends Collection> type) {

        // Record info
        this.recordGetterModel(a, method, name, fieldModel);

        // Get element info
        Type rtype = method.getGenericReturnType();
        if (!(rtype instanceof ParameterizedType))
            throw new InvalidAnnotationException(a, method, "method does not return a generic collection type");
        if (!getRawType(a, method, rtype).isAssignableFrom(type))
            throw new InvalidAnnotationException(a, method, "method does not return (a superclass of) " + type);
        Type elemType = ((ParameterizedType)rtype).getActualTypeArguments()[0];
        SimpleFieldModel elementModel = createSimpleField(a, method, elemType, true);

        // Record collection type info
        fieldModel.setElementModel(elementModel);
        fieldModel.setAccessMethod(method);
        this.log.debug("found " + a + " annotation on method " + method);
    }
}

